home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / dis86122.arc / DIS86.DOC next >
Text File  |  1988-01-16  |  25KB  |  676 lines

  1.                          dis86 - Interactive 8086 Disassembler
  2.  
  3.   (C) COPYRIGHT 1985, 86, 87 by James R. Van Zandt,  ALL RIGHTS RESERVED
  4.  
  5.  
  6.  
  7.  
  8. You are encouraged to copy and distribute this program freely, provided:
  9.  
  10.     1)    No fee is charged beyond the actual cost for such copying and
  11.         distribution.
  12.  
  13.     2)    It is distributed ONLY in its original, unmodified state.
  14.  
  15. If you like this program, and find it of use, then your contribution of
  16. $25 will be appreciated.  A current version program disk and printed
  17. documentation are available if you send $50 to:
  18.  
  19.             James R. Van Zandt
  20.             27 Spencer Dr.
  21.             Nashua NH 03062
  22.             603-888-2272
  23.  
  24. SYNOPSIS
  25.  
  26. ûDis86 is a full-screen, interactive disassembler of object code for
  27. the 8086, 8087, 8088, 80186, 80286, and 80386 (products of Intel), and 
  28. the V20 and V30 (products of NEC).  The 80386 disassemblies include 32 
  29. bit operands and addresses.  Dis86 implements the concept of a "current 
  30. location: and allows use of the cursor keys to change it.  Code can come 
  31. from a .EXE file (in which case the header is properly interpreted), any 
  32. other file (assumed to have no header), or anywhere in main memory 
  33. (0000:0000 - F000:FFFF).  It can also read and write using absolute disk
  34. addresses (in which case the disk organization is shown).  Dis86 can
  35. install changes, even in a .EXE file, making it a convenient way to
  36. install patches.  Versions are available for the IBM PC (and clones)
  37. and Z-100.
  38.  
  39.  
  40. REVISION HISTORY
  41.  
  42. 1.00   First publically released version.
  43. 1.10   Implemented s-i-b byte for 80386 code (previously omitted due to
  44.        oversight).
  45. 1.11   Reversed bx+disp and bp+disp codes.
  46. 1.12   Installed F format.
  47. 1.13   Fixed several small disassembly errors, installed V command.
  48.        Reversed bx+disp and bp+disp codes again...NOTE: description in
  49.        preliminary 80386 manual is WRONG.
  50. 1.14   V command installed.  Follows interrupts if disassembling from memory.
  51. 1.15   Minor style changes, V command copies expression to reply line.
  52. 1.20   Absolute disk address mode installed.
  53. 1.21   Eliminating trailing blanks in printout.
  54. 1.22   Following FAT entries.
  55.  
  56.  
  57. STARTING THE DISASSEMBLER
  58.  
  59. To disassemble a file, give the file name (optionally preceded by a path 
  60. name) on the command line:
  61.  
  62.         A>dis86 foo.exe
  63.  
  64. To disassemble from RAM, use an empty command line:
  65.  
  66.         A>dis86
  67.  
  68. To disassemble using absolute disk addresses, specify only the disk on
  69. the command line:
  70.  
  71.         A>dis86 b:
  72.  
  73. There are no command line switches.
  74.  
  75.  
  76. HEADER INFORMATION
  77.  
  78. The information in the .EXE file header, or the organization of the
  79. disk in absolute disk address mode, will be displayed when the program
  80. is first run and in response to the H command (see below).
  81.  
  82.  
  83. DISPLAY SCREEN
  84.  
  85. During disassembly, the screen will resemble the following:
  86.  
  87.         0000:0100      e9 01 90            jmp            9104
  88.         0000:0103      55                  push           bp       
  89.         0000:0104      8b ec               mov            bp,sp    
  90.         0000:0106      83 ec 0e            sub            sp,0e    
  91.         
  92.                                   ...
  93.         
  94.         0000:012C      50                  push           ax         
  95.         0000:012D      b8 69 00            mov            ax,0069    
  96.         0000:0130      50                  push           ax         
  97.         0000:0131      e8 e9 5c            call           5e1d       
  98.         dis86 1.00 - A SHAREWARE software product  (c) 1986, James R. Van Zandt
  99.         >
  100.         ... 0000:0100  0000:0100  0000:0100  
  101.  
  102. Lines 1 through 21 are the disassembled code.  Each line starts with
  103. the current address, followed by the actual bytes being disassembled. 
  104. The rest of the line is the assembly language equivalent, if any, of
  105. the code.  The display for A (ASCII), B (byte), D (data), F (font), and
  106. U (File Allocation Table) formats is similar.  All numbers are shown in
  107. hexadecimal.  
  108.  
  109. Line 22 is a message and prompt line showing, for example, the
  110. arguments needed for some commands.  Line 23 has the prompt.  Typed
  111. characters are echoed on the rest of this line.  Line 24 has three
  112. addresses, which are the top three entries in the stack (see the
  113. 'cursor right' and 'cursor left' commands below).
  114.  
  115.  
  116. CURSOR KEYS
  117.  
  118. The "current location" is the address displayed on the first line
  119. of disassembly.  The cursor keys are used to adjust the current 
  120. location.
  121.  
  122. The up and down cursor keys (8 and 2 on the numeric pad) are used to
  123. move the current location a small amount.  <up> moves by one line
  124. except in C (code) format, when it moves up by one byte. (Note that <up>
  125. and <down> are not inverses in this case.):
  126.  
  127.         <up>     moves up by one line or byte (lower address)
  128.         <down>   moves down by one line (higher address)
  129.  
  130.  
  131. The <pg up> and <pg dn> keys (9 and 3 on the numeric pad) move the
  132. current location by larger amounts.  In C (code) format, they move by
  133. 32 bytes.  In the other formats, they move by 11 lines on the screen. 
  134. They will not move the cursor out of the disassembly buffer. 
  135. Otherwise, they are inverses.:
  136.  
  137.         <pg up>   moves up by 32 bytes (lower address)
  138.         <pg dn>   moves down by 32 bytes (higher address)
  139.  
  140.  
  141. The above keys change only the current location.  Other commands change 
  142. the current location by potentially large amounts, but first save it in 
  143. a stack.  The top three addresses in the stack are shown in the command
  144. area at the bottom of the screen.
  145.  
  146. If the instruction at the current location is a jump, call, or a
  147. reference to a data location, the cursor right key (6 on the numeric
  148. pad) will push the current location on the stack and go to the
  149. referenced location.  If the disassembly is from memory, interrupts can
  150. also be followed.  For a data reference, the disassembly format is
  151. changed to D (hex and ASCII).  If disassembly is from disk using
  152. absolute disk references and the disassembly format is U (display File
  153. Allocation Table, or FAT), then the next FAT entry is followed.
  154.  
  155.         <right>   follows a jump, call, interrupt, 
  156.                   data reference, or FAT entry
  157.  
  158. If disassembling a FAT, the next entry is followed, staying within the
  159. same FAT.  If disassembling from an address above the last FAT, the
  160. disassembler assumes a directory entry is being displayed, finds the
  161. next FAT reference (displacement 1A from the beginning of the current
  162. directory entry, which begins on a 32 byte boundary), and follows it
  163. into the first FAT.  Note that the disassembly format must be U before
  164. the disassembler will attempt to follow a FAT entry.  The usual format
  165. for a directory entry would be D or A.  The correct sequence in that
  166. case would be U <ret> <right>.
  167.  
  168. The cursor left or left arrow key (4 on the numeric pad) will pop the
  169. last address off the stack.  Note that right arrow followed by left
  170. arrow will return you to the same address, whereas left arrow
  171. (returning, let us say, to address X) followed by right arrow will only
  172. return you to the same address if there is an appropriate jump, call,
  173. or data reference at X.
  174.  
  175.         <left>    pops address stack
  176.  
  177. After using the right arrow or one of the commands A, B, C, D, F, or G
  178. (in the next section) to go to a new address, then using the left arrow
  179. key to pop the stack, you will sometimes want to return to the previous
  180. address.  The stack no longer holds the address.  However, the left
  181. arrow key saves the current location in a special "previous state"
  182. before popping the stack.
  183.  
  184. To return to the address stored in the "previous state", type shift
  185. right arrow on a Z-100, or control right arrow on an IBM PC.
  186.  
  187.         <shift><right>   returns to "previous state"   (Z-100)
  188.         <cntrl><right>   returns to "previous state"   (IBM)
  189.  
  190.  
  191. In summary, the unshifted keys on the numeric pad are:
  192.  
  193. <home> top of file          ^   up 1 line         <pg up>  up 32 bytes 
  194.                             |         
  195.  
  196. <--    pop addr stack                             -->      follow jump/call
  197.  
  198.                             |         
  199. <end>  end of file          v  down 1 line        <pg dn>  down 32 bytes  
  200.  
  201.  
  202. <ins>  setup options 
  203.  
  204. On the Z-100, the four keys with arrows on them may be used in addition
  205. to the 2, 4, 6, and 8 on the numeric pad.
  206.  
  207.  
  208. LETTER COMMANDS FOR MOVING THE CURSOR
  209.  
  210. There are seven letter commands to change the display format and/or
  211. disassembly address:
  212.  
  213.     A    ASCII data
  214.     B    byte data (hex)
  215.     D    data (both hex bytes and ASCII)
  216.     C    code
  217.     F   font
  218.     G    goto
  219.     U   File Allocation Table entry
  220.  
  221. These commands may be in upper or lower case.  Each may be followed by:
  222.  
  223.     <ret>        Only the display format changes.
  224.  
  225.     A <expression> <ret>
  226.             The current location changes to the specified address.
  227.  
  228.     S <expression> <expression> <expression> <ret>
  229.             The disassembler searches from the current
  230.             address to the end of the buffer for the
  231.             specified sequence of hex bytes.  If an
  232.             expression has a segment specified using the
  233.             ':' operator (below), the segment is ignored.
  234.  
  235.     S T [string] <ret>
  236.             The disassembler searches from the current
  237.             address to the end of the buffer for the
  238.             specified ASCII string.  Cases are not
  239.             distinct, and the high order bit is ignored. 
  240.             The string can also be introduced by a double
  241.             quote.
  242.  
  243.     S R <expression> <ret>
  244.             The disassembler searches from the current
  245.             address to the end of the buffer for a
  246.             reference (jump or call) to the specified
  247.             address.
  248.  
  249. An <expression> can involve any of these items:
  250.  
  251.     hex numbers    (either upper or lower case letters)
  252.     cs, ds, es, ss, fs, gs
  253.             currently assumed segment register values
  254.     $        current location
  255.     @        offset of top address on the stack
  256.     'x'        single characters
  257.     "jkl;"        multiple character strings
  258.  
  259. ...and any of these operators:
  260.  
  261.     + - * /        add, subtract, multiply, divide
  262.     :        separate segment and offset
  263.  
  264. Note that G with no address is a noop.  
  265.  
  266. There are two ways to ask for a string search.  For example,
  267.  
  268.     S T jones
  269.  
  270.     S "Jones"
  271.  
  272. In the first search, cases are not distinct and the high order bit
  273. is ignored.  In the second search, the high order bit must be 0 and
  274. the cases must match.
  275.  
  276. In F format, one byte is shown per line, and each bit in that byte is
  277. represented by an astrisk.  This is suitable for displaying fonts for
  278. video displays, which are uniformly 8 bits wide.
  279.  
  280. In U (clUster number) format, bytes are displayed as File Allocation
  281. Table, or FAT entries.  This format is ordinarily useful only when
  282. disassembling using absolute disk addresses.  In that case, the
  283. disassembler will have determined how many clusters there are on the
  284. disk.  If there are fewer than 4097, then 12 bit FAT entries are
  285. assumed.  If there are 4097 or more, then 16 bit FAT entries are
  286. assumed.  Each pair of 12 bit FAT entries obviously occupies three
  287. bytes.  If the cursor is set on the third byte of a pair of 12 bit
  288. entries, or the second byte of a 16 bit entry, the disassembler
  289. displays some dashes to signal that it is skipping that byte. 
  290. Otherwise, it starts by displaying the FAT entry that begins with that
  291. byte.
  292.  
  293. There are many explanations of how File Allocation Tables work.  One
  294. good one is in Ray Duncan's book "Advanced MSDOS" (Microsoft Press,
  295. 1986).
  296.  
  297. OPTIONS
  298.  
  299. The 'O' command or <ins> (0 on the numeric pad) bring up menus for
  300. changing setup options and allow the user to reset the disassembly
  301. window.  Use <space> or <ins> to move to the next screen, or <esc> to
  302. return to disassembly.
  303.  
  304. In the first options menu, use the right and left cursor keys or <ret>
  305. to change the entries.  The first item shows the processor which is
  306. supposed to execute the code being disassembled.  There is some
  307. conflict in op codes between the V20 and V30 on one hand and the 80286
  308. and 80386 on the other.  That is, the two families use the same op
  309. codes for different instructions.  Dis86 selects the instruction
  310. appropriate for the chip shown in this menu.  In addition, instructions
  311. not implemented by the indicated chip will be flagged.  The second item
  312. on the first menu lets the user specify 16 or 32 bit mode for the
  313. 80386.  In the 16 bit mode the 80386 is similar to the 8086.  In the 32
  314. bit mode arithmetic is performed in 32 bit registers and all address
  315. offsets are 32 bits.  (The 80386 itself selects the mode based on a bit
  316. in the segment table entry for the code segment.) The last two items
  317. allow selection of the colors on an IBM color display.
  318.  
  319. In the second options menu, change an entry by typing over it.  The two
  320. items are the byte value which matches anything in a byte or character
  321. search (the "wild card" byte) and the number of bytes displayed on each
  322. line for the A, B, or D formats.  The latter value can also be set
  323. using the W command.
  324.  
  325. The last options display is a small map of the code being disassembled
  326. which will resemble the following:
  327.  
  328.         ds= -10
  329.         cs=0000
  330.         |                  ss=0960
  331.         es= -10            |
  332.         | cursor=0000:0453 |
  333.         CCCCCCCCCCCCCCcccccccccccccc
  334.         ^0000:0000
  335.                      ^0000:6144
  336.  
  337. The Cs represent the code being disassembled.  The capital Cs are the
  338. portion of code in the disassembly window (see discussion below).  The
  339. assumed values for the segment registers, the current location (labeled
  340. "cursor"), and the beginning and end addresses of the disassembly
  341. window are also shown.  The window can be adjusted using the right and
  342. left cursor keys.
  343.  
  344. By using the <ins> key to enter the options menu and to step from one
  345. menu to the next, you can leave your right hand on the numeric pad.
  346.  
  347.  
  348. MISCELLANEOUS COMMANDS
  349.  
  350. The 'P' command is used to print a disassembly listing to a file.  The
  351. first time this command is used, it prompts for a file name.  The
  352. default file name is "printout".  To actually send the listing to a
  353. printer, specify the filename "prn".  If the file already exists the
  354. new information will be appended.  The file is automatically closed
  355. before the disassembler exits.  The command also prompts for the
  356. beginning and end addresses of the code to be printed.  The default
  357. addresses print the current screen.  When the printing is finished, the
  358. current address is advanced to the first byte not printed.  Thus, you
  359. can repeat the sequence
  360.  
  361.         P <ret> <ret>
  362.  
  363. to print a large section.
  364.  
  365. Enter 'R' to display and/or change the assumed segment register values.
  366. Entries may be full expressions.  For example, to copy the value from SS 
  367. into DS, use the cursor keys to select the DS register and type
  368.  
  369.         ss <ret>
  370.  
  371.  
  372. The 'S' command selects a new segment register value for displaying 
  373. addresses.  The new register is shown on the message line.  The actual 
  374. address being disassembled is not changed (see "segmentation" below).
  375.  
  376. The 'V' command requests an expression and displays its value.
  377.  
  378. The 'W' command is used to set the number of bytes displayed on each
  379. line for the A, B, and D formats.  This is useful for displaying
  380. tables.  For example, when dis86 is executed without a file, it
  381. displays bytes starting at address 0000:0000 and the width is set to
  382. four so each interrupt vector is shown on a separate line.
  383.  
  384. Type '?' to get a series of help screens.  Type <esc> to return to the
  385. disassembly, or any other key to advance to the next screen
  386.  
  387. The 'E' command allows the user to modify the program being
  388. disassembled.  Changes are initially made only in the disassembly
  389. buffer.  Before the buffer is overwritten or the disassembler
  390. terminates, the user is asked whether the changes are to be written to
  391. the file or RAM area being disassembled.  The values entered may be
  392. given in hex expressions or ASCII.  Values too large to fit into a byte
  393. are assumed to be words or double words.  Here are some examples:
  394.  
  395.     45 67 'A'            =>  45 67 41
  396.  
  397.     2ea+3                =>  ed 02
  398.  
  399.     9c/3                 =>  34
  400.  
  401.     "Alpha Beta" 0d 0a   =>  41 6c 70 68 61 20 42 65 74 61 0d 0a
  402.  
  403.  
  404. Enter 'Q' to stop the disassembler and return to DOS.
  405.  
  406.  
  407. TYPING REQUESTED DATA
  408.  
  409. Many commands supply default entries for requested data.  If you decide
  410. to accept the default, just enter <ret>.  For editing entries,
  411. you can position the cursor using the left and right cursor keys to
  412. move by one character, <home> (7 on the numeric pad) to move to the
  413. left end of the string, or <end> (1 on the numeric pad) to move to the
  414. right end.  Use the <del> or <backspace> keys to delete incorrect
  415. characters, or just type characters to be inserted.  (There is no
  416. "replace" typing mode.) In every case but one, you can also edit the
  417. default entry by making <right>, <end>, or <del> your first keystroke. 
  418. The exception is the default for the byte search function.
  419.  
  420. In edit mode, the four active keys on the numeric pad are:
  421.  
  422. <home> start of string      ^                     <pg up> 
  423.                             |         
  424.  
  425. <--    left one char                              -->      right one char
  426.  
  427.                             |         
  428. <end>  end of string        v                     <pg dn> 
  429.  
  430.  
  431. DISASSEMBLY WINDOW
  432.  
  433. The disassembler uses a buffer to hold the code being disassembled. 
  434. For most purposes, this disassembly window is transparent to the user. 
  435. If the user requests an address within the file but outside the
  436. disassembly window, the appropriate code is automatically read in.  The
  437. existence of the window is apparent in only three cases: 
  438.  
  439.     1.    If the disassembler is started near the end of the window 
  440.         and reaches the end before it fills the screen, the
  441.         rest of the screen will be left blank.
  442.  
  443.     2.    The searches are done only from the current location to the
  444.         end of the buffer.
  445.  
  446.     3.    If the contents of the buffer has been changed (see 'E'
  447.         command) the user is asked whether they should be
  448.         written out before the buffer is overwritten or control 
  449.         is returned to DOS.
  450.  
  451.  
  452. LOAD ADDRESS
  453.  
  454. Code from a .COM file is displayed as though its Program Segment Prefix
  455. were at 0000:0000 and its load address were 0000:0100.
  456.  
  457. Code from a .EXE file is displayed as though its load address were
  458. 0000:0000.  This puts its Program Segment Prefix is 10 paragraphs or
  459. 100 (hex) bytes lower.  This is somewhat awkward, because the DS and ES
  460. registers are initialized to point to the PSP.  The disassembler
  461. displays this segment value as -10.  The advantage of a load address of
  462. 0000:0000 is that no relocation is necessary.  The bytes displayed are
  463. exactly the same as those in the file.  This also means that the code
  464. can be modified (see below for the 'E' command) and written back to the
  465. file without being "unrelocated".
  466.  
  467.  
  468. SEGMENTATION
  469.  
  470. Addresses are displayed in segment:offset form, using the current
  471. assumed value of the current segment register.  The current segment 
  472. register can be selected using the 'S' command to step among the 
  473. available registers (CS, SS, DS, ES, FS, and GS - the last two only with 
  474. 80386 code).  Changing segment registers or their values does not move 
  475. the disassembler cursor.  Only the displayed segment and offset values 
  476. will change to reflect the new assumptions.  A legal offset will be
  477. displayed as a four digit hex number (0000 to FFFF).  Other offsets
  478. (negative, or greater than 64K) will also be calculated and displayed
  479. correctly, although they are illegal on the 8086.  Illegal offsets will
  480. have more than four digits.  
  481.  
  482. The segment register values are initialized as indicated in the file 
  483. header (for .EXE files) or to zero (for other files or RAM).  The 
  484. disassembler has no way of determining the values which may be set 
  485. during execution.  For example, the initialization code for DeSmet C 
  486. programs reset DS to the same value as the initial SS before executing 
  487. main().
  488.  
  489. The assumed segment register values can be altered in two ways.  Any 
  490. segment register can be changed using the register menu reached by the 
  491. 'R' command.  In addition, when the right arrow key is used to follow a 
  492. far call or jump, the new code segment value is loaded into the CS 
  493. register.  When the user specifies a new segment value on an A, B, C, D, 
  494. or G command, that value is used for subsequent displays but none of the 
  495. assumed segment register values is changed.
  496.  
  497. The segmentation models of the protected modes of the 80286 and 80386 
  498. are not supported.
  499.  
  500.  
  501. ALIGNMENT
  502.  
  503. Dis86 will correctly disassemble code if started on the first byte of an 
  504. instruction.  If started in the middle of an instruction, it will 
  505. disassemble that instruction and perhaps several more incorrectly.  In 
  506. this case the disassembler is said to be out of alignment with the 
  507. object code.  The disassembler will tend to correct its alignment if it 
  508. continues long enough.  8086 instructions tend to be longer than, for 
  509. example, those for the 8080, so the disassembler will tend to stay out 
  510. of alignment for more bytes.  Generally speaking, the alignment will be 
  511. correct after the first half dozen lines.
  512.  
  513.  
  514. SUMMARY
  515.  
  516. Here are all the letter commands:
  517.  
  518. A nnnn      ASCII data
  519. B nnnn      byte date (hex)
  520. C nnnn      code (disassembly)
  521. D nnnn      data (hex and ASCII)
  522. F nnnn      font
  523. E           enter new data (follow with a series of hex expressions)
  524.  
  525. G nnnn      goto address nnnn
  526. H           display file header information (for .EXE files only)
  527. O           change setup options
  528. P           print disassembly listing to file
  529. Q           quit to DOS
  530.  
  531. R           change segment register values
  532. S           select a new segment register
  533. V           evaluates an expression
  534. W           set bytes of data per line for A, B, and D formats
  535. X           exchange current address (at top of screen) with top of stack
  536. ?           display help screens
  537. /           display list of alphabetic commands on message line
  538.  
  539.  
  540. EXAMPLE 1
  541.  
  542. In the examples, <left>, <right>, <up>, and <down> refer to the four
  543. cursor keys (4, 6, 8, and 2 on the numeric pad, plus the four arrow
  544. keys on the Z-100 keyboard).  <pg up> and <pg dn> refer to the 9 and 3
  545. on the numeric pad.
  546.  
  547. To investigate the bootstrap code, type
  548.  
  549.     A>dis86 <ret>
  550.  
  551. and press
  552.  
  553.     <space>
  554.  
  555. to advance to the disassembly display, which will be a D (data) format 
  556. display of the interrupt vectors.  Next type
  557.  
  558.     c a ffff:0000 <ret>
  559.  
  560. (for Code format at the Address ffff:0000).  On an IBM, the ROM release 
  561. date and machine ID appear in the last 16 bytes of the ROM.  To see 
  562. them, type
  563.  
  564.     D <ret>
  565.  
  566. The release data is at addresses ffff:0005 - ffff:000c in ASCII.  The 
  567. machine ID is at ffff:000e.  Some of the possible values are:
  568.  
  569.     ff    IBM PC
  570.     fe    IBM XT and Portable IBM PC
  571.     fd    IBM PCjr
  572.     fc    IBM AT
  573.     2d    Compaq
  574.     9a    Compaq-Plus
  575.  
  576. Return to code format by typing
  577.  
  578.     C <ret>
  579.  
  580. One of the instructions displayed will almost certainly be a jump.  If 
  581. so, press
  582.  
  583.     <down>
  584.  
  585. enough times to bring the jump to the top line, then
  586.  
  587.     <right>
  588.  
  589. to follow the jump.  Note that the previous addresses were pushed onto 
  590. the stack, as shown on the bottom line.  To return to the most recent 
  591. address, press
  592.  
  593.     <left>
  594.  
  595. To leave the disassembler, press
  596.  
  597.     Q
  598.  
  599.  
  600. EXAMPLE 2
  601.  
  602. For a second example, let us disassemble the disassembler itself.  Begin 
  603. by typing
  604.  
  605.     A>dis86 dis86.exe <ret>
  606.  
  607. Note the header information, including the entry point of 0000:0000 and 
  608. the initial stack location of approximately 09e0:9eb8.  Proceed to the 
  609. disassembly screen by typing
  610.  
  611.     <space>
  612.  
  613. The disassembler starts in C (code) format at the entry point, which is 
  614. a jump to the initialization code.  To follow the jump, type
  615.  
  616.     <right>
  617.  
  618. One of the early instructions in the initialization code refers to the 
  619. first location in the stack segment.  Bring this location to the top of 
  620. the screen by typing
  621.  
  622.     <pg dn> <down> <down>
  623.  
  624. and follow the reference by typing
  625.  
  626.     <right>
  627.  
  628. Since it was a data reference, the disassembler automatically switched 
  629. to D (data) format.  Also, the addresses are displayed using the value 
  630. of segment register SS.  Note that the two previous addresses have been 
  631. pushed onto the stack, as shown at the bottom of the screen.  Return to 
  632. the most recent one by typing
  633.  
  634.     <left>
  635.  
  636. The initialization code gets rather involved, but one of its functions
  637. is to initialize DS to the same value as SS.  To reflect this, use the
  638. R command:
  639.  
  640.     R
  641.  
  642. DS is the first register in the list, so you need only enter the 
  643. appropriate value:
  644.  
  645.     ss <ret> <space>
  646.  
  647. The code for the main program immediately followed the jump at 
  648. 0000:0000.  To return there, type
  649.  
  650.     <left>
  651.  
  652. Send a copy of this screen to the file "printout" by typing
  653.  
  654.     P <ret> <ret> <ret>
  655.  
  656. To inspect the data segment, type
  657.  
  658.     A ds:0 <ret>
  659.  
  660. To display more characters on each line, use the W command:
  661.  
  662.     W 60 <ret>
  663.  
  664. Use the search command to find one of the messages:
  665.  
  666.     G S T hime <ret>
  667.  
  668. This string won't be found.  To correct the spelling to "home" and try 
  669. again, type
  670.  
  671.     G S T <right> o <del> <ret>
  672.  
  673. Once again, leave the disassembler by pressing
  674.  
  675.     Q
  676.